HIDL Hal 开发指南9 —— 添加硬件访问服务

3/29/2024

# 添加 aidl 文件

添加 aidl 文件 frameworks/base/core/java/android/os/IHelloService.aidl :

package android.os;

interface IHelloService
{
    void write(String str);
    String read();
}
1
2
3
4
5
6
7

frameworks/base/Android.bp 中添加上 aidl 文件:

java_defaults {
    name: "framework-defaults",
    installable: true,

    srcs: [
        // ......
        "core/java/android/os/IUserManager.aidl",
        ":libvibrator_aidl",
        "core/java/android/os/IVibratorService.aidl",
        // 添加的内容
        "core/java/android/os/IHelloService.aidl", 
        "core/java/android/os/image/IDynamicSystemService.aidl",
        "core/java/android/os/storage/IStorageManager.aidl",
        "core/java/android/os/storage/IStorageEventListener.aid
        // ......
    ]
    //.....
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 实现服务端

添加 frameworks/base/services/core/java/com/android/server/HelloService.java 文件:

package com.android.server;

import android.os.IHelloService;

// 硬件服务的服务端实现
public class HelloService extends IHelloService.Stub {

    public native void natvieWrite(String str);
    public native String nativeRead();
    
    public void write(String str) throws android.os.RemoteException  {
        natvieWrite(str);
    }
    
    public String read() throws android.os.RemoteException  {
        return nativeRead();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# JNI 层实现

添加 frameworks/base/services/core/jni/com_android_server_HelloService.cpp JNI 实现:

#define LOG_TAG "HelloService"

#include <jni.h>
#include "android_runtime/AndroidRuntime.h"

#include <utils/misc.h>
#include <utils/Log.h>

#include <stdio.h>
#include <string>

#include <nativehelper/JNIHelp.h>

#include <jelly/hardware/hello_hidl/1.0/IHello.h>
#include <hidl/LegacySupport.h>

using android::sp;
using jelly::hardware::hello_hidl::V1_0::IHello;
using android::hardware::Return;
using android::hardware::hidl_string;


namespace android
{

static void helloWrite(JNIEnv* env, jobject clazz, jstring str)
{   
   // 获取服务代理端对象
    android::sp<IHello> hw_device = IHello::getService();
    if (hw_device == nullptr) {
              ALOGD("failed to get hello-hidl");
              return;
    }
    const char* cStr = env->GetStringUTFChars(str, 0);
    // 通过代理端对象发起远程调用
    hw_device->write(cStr);
}

static jstring helloRead(JNIEnv* env, jobject clazz)
{
    jstring res = nullptr;
   // 获取服务代理端对象
    android::sp<IHello> hw_device = IHello::getService();
    if (hw_device == nullptr) {
              ALOGD("failed to get hello-hidl");
              return res;
    }

    hw_device->read([&](hidl_string result){
        ALOGD("%s\n", result.c_str());
        res = env->NewStringUTF(result.c_str());
    });

    return res;
}

    // public native void natvieOpen();
    // public native void natvieWrite(String str);
    // public native String nativeRead();

static const JNINativeMethod method_table[] = {

    { "natvieWrite", "(Ljava/lang/String;)V", (void*)helloWrite },
    { "nativeRead", "()Ljava/lang/String;", (void*)helloRead }
};


int register_android_server_HelloService(JNIEnv *env)
{   
    ALOGD("yuandaima_jni_register");
    return jniRegisterNativeMethods(env, "com/android/server/HelloService",
            method_table, NELEM(method_table));
}

};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

frameworks/base/services/core/jni/Android.bp 中添加:

srcs: [
        // ......
        "com_android_server_vr_VrManagerService.cpp",
        "com_android_server_UsbAlsaJackDetector.cpp",
        "com_android_server_UsbDeviceManager.cpp",
        "com_android_server_UsbDescriptorParser.cpp",
        "com_android_server_UsbMidiDevice.cpp",
        "com_android_server_UsbHostManager.cpp",
        "com_android_server_VibratorService.cpp",
        // 添加的内容
        "com_android_server_HelloService.cpp"
        "com_android_server_PersistentDataBlockService.cpp",
        "com_android_server_GraphicsStatsService.cpp",
        // ......
    ],
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

frameworks/base/services/core/jni/onload.cpp 中添加:

namespace android {
    // ......
    int register_android_server_vr_VrManagerService(JNIEnv* env);
    //添加的内容
    int register_android_server_HelloService(JNIEnv* env);
    int register_android_server_VibratorService(JNIEnv* env);
    int register_android_server_location_GnssLocationProvider(JNIEnv* env);
    int register_android_server_connectivity_Vpn(JNIEnv* env);
    // .....
}


// 在这里注册 JNI 函数
// java 层的 native 方法就能调用到对应的 native 层函数了
extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
    JNIEnv* env = NULL;
    jint result = -1;

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        ALOGE("GetEnv failed!");
        return result;
    }
    ALOG_ASSERT(env, "Could not retrieve the env!");

    register_android_server_ActivityManagerService(env);
    register_android_server_PowerManagerService(env);
      // ......
    register_android_server_VibratorService(env);
     // 添加的内容
    register_android_server_HelloService(env);
    register_android_server_SystemServer(env);
    register_android_server_location_GnssLocationProvider(env);
    register_android_server_location_FlpHardwareProvider(env);
    // ......
    return JNI_VERSION_1_4;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# 客户端接口实现

添加一个接口 frameworks/base/core/java/android/os/HelloHal.java

package android.os;

import android.app.ActivityThread;
import android.content.Context;


public abstract class HelloHal {

    public HelloHal() {
    }

    public abstract int write(String st) throws RemoteException;
    
    public abstract String read() throws RemoteException;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

实现接口 frameworks/base/core/java/android/os/SystemHelloHal.java

package android.os;

import android.content.Context;
import android.util.Log;

/**
 * Vibrator implementation that controls the main system vibrator.
 *
 * @hide
 */
public class SystemHelloHal extends HelloHal {
    
    private static final String TAG = "HelloHal";

    private final IHelloService mService;

      // 获取Hello服务的代理端
    public SystemHelloHal() { 
        mService = IHelloService.Stub.asInterface(
                ServiceManager.getService("hello"));
    }
 
    @Override
    public int write(String str) throws RemoteException {
        if (mService != null) {
            mService.write(str);
        }
        return -1;
    }
    
    @Override
    public String read() throws RemoteException {
        if (mService != null) {
            return mService.read();
        }
        return null;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

frameworks/base/core/java/android/content/Context.java 中添加:

    public static final String HELLO_SERVICE = "hello";

        @StringDef(suffix = { "_SERVICE" }, value = {
            HELLO_SERVICE,    
            POWER_SERVICE,
            //......
1
2
3
4
5
6

接着在 SystemServiceRegistry 的静态块中添加:

// frameworks/base/core/java/android/app/SystemServiceRegistry.java

//不要忘了 import
import android.os.HelloHal;
import android.os.SystemHelloHal;

      static {
        registerService(Context.HELLO_SERVICE, HelloHal.class,
            new CachedServiceFetcher<HelloHal>() {
            @Override
            public HelloHal createService(ContextImpl ctx) {
                return new SystemHelloHal();
            }});
      }
1
2
3
4
5
6
7
8
9
10
11
12
13
14

最后修改 frameworks/base/services/java/com/android/server/SystemServer.java:


    private void startOtherServices() {
        final Context context = mSystemContext;
        VibratorService vibrator = null;
        //添加内容
        HelloService helloService = null;
        DynamicSystemService dynamicSystem = null;
        // ......

        traceBeginAndSlog("StartVibratorService");
        vibrator = new VibratorService(context);
        ServiceManager.addService("vibrator", vibrator);
        traceEnd();

        traceBeginAndSlog("StartHelloService");
        helloService = new HelloService(context);
        ServiceManager.addService(Context.HELLO_SERVICE, helloService);
        traceEnd();        

        // ......
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# Selinux 配置

修改 system/sepolicy/private/service.tesystem/sepolicy/prebuilts/api/29.0/private/service.te,注意保持两个文件内容一致:

type HelloServiceType, app_api_service, system_server_service, service_manager_type;
1

修改 system/sepolicy/private/service_contextssystem/sepolicy/prebuilts/api/29.0/private/service_contexts,注意保持两个文件内容一致:

HelloService                              u:object_r:HelloServiceType:s0
1

修改 system/sepolicy/private/platform_app.tesystem/sepolicy/prebuilts/api/29.0/private/platform_app.te,让系统 App 可以访问我们自定义的 Binder 服务:

allow platform_app HelloServiceType:service_manager find;
1

最后,让 SystemServer 可以访问到 HelloService,修改 system/sepolicy/private/system_server.tesystem/sepolicy/prebuilts/api/29.0/private/system_server.te:

hwbinder_use(system_server);
allow system_server HelloServiceType:service_manager { add find };
1
2

添加 device/jelly/rice14/sepolicy/system_server.te

get_prop(system_server, hwservicemanager_prop);

allow system_server hello_hidl_hwservice:hwservice_manager { find };

allow system_server hello_hidl:binder { call };

hwbinder_use(system_server);
1
2
3
4
5
6
7

# 编译运行

source build/envsetup.sh
lunch rice14-eng
make -j32
# 启动模拟器
emulator -kernel ~/Project/kernel/goldfish/arch/x86_64/boot/bzImage
1
2
3
4
5